package java_option.player.javacv.core;

import java.text.SimpleDateFormat;

import java_option.player.javacv.util.Sleep;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;

/**
 * <pre>
 *   视频帧队列FIFO
 *   播放的时候先播放视频、然后播放音频
 *   播放的时候检查 FrameWrapper的的时间戳
 * </pre>
 * 
 * @author java红了 <br/>
 *         2020-9-2719:34:52
 */
public class VideoPlayThread extends Thread {

	private static VideoPlayThread instance;
	private Canvas mCanvas;
	private GraphicsContext graphicsContext;
	private Boolean isRunning = false;

	private VideoPlayThread() {

	}

	public static VideoPlayThread getInstance() {
		synchronized (VideoPlayThread.class) {
			if (instance == null) {
				instance = new VideoPlayThread();
			}
		}
		return instance;
	}

	public void startPlay(Canvas canvas) {
		this.mCanvas = canvas;
		graphicsContext = canvas.getGraphicsContext2D();
		// 启动线程
		super.start();
	}

	@Override
	public void start() {
		throw new RuntimeException("请调用 startPlay#canvas");
	}

	@Override
	public void run() {
		isRunning = true;
		long preFrameNanoTime = 0;// 上一帧处理时的时间(单位纳秒)
		long preFrameTimestamp = 0;// 上一帧的timestamp -- (单位微秒)
		long consumNanoTime = 0; // 实际显示一帧花费的时间 (单位纳秒)
		long frameDiffRealTimestamp = 0; // 两帧之间实际间隔的时间 -- (单位微秒)

		while (true) {

			if (isRunning == null) {
				// 清空画布
				System.out.println("清空画布");
				graphicsContext.clearRect(0, 0, this.mCanvas.getWidth(), this.mCanvas.getHeight());
				break;
			}

			if (isRunning == false) {
				waitPlay();
			}

			FrameWrapper videoWrapper = FrameFIFO.getInstance().readNextVideo();
			if (videoWrapper == null) {
				continue;
			}
			System.out.println("video == >" + videoWrapper.index);
			// 如果播放上一帧花费的时间、两帧之间的时间
			consumNanoTime = System.nanoTime() - preFrameNanoTime;
			frameDiffRealTimestamp = (videoWrapper.frame.timestamp - preFrameTimestamp);
			// 解决拖动slider进度条卡住的问题
			if (frameDiffRealTimestamp > 100000) {
				frameDiffRealTimestamp = 100000;
			}
			// System.out.println(consumNanoTime + " --11-- " + frameDiffRealTimestamp);
			// 音视频时间同步、视频-音频的时间戳的差
			long videoSubAudioTimestampDiff = FrameFIFO.getInstance().getVideoSubAudioTimestampDiff();
//			System.out.println("-------------------- " + consumNanoTime + " , " + videoSubAudioTimestampDiff);
			// 视频播放比音频快快
			if (videoSubAudioTimestampDiff > 0) {
				System.out.println(Thread.currentThread());
				System.out.println("1_" + System.nanoTime());
				Sleep.sleep(consumNanoTime, frameDiffRealTimestamp * 1000);
				System.out.println("2_" + System.nanoTime());
				// 因为视频比音频快、需要额外sleep 把视频速度调慢 等音频时间同步
				try {
					System.out.println("额外sleep 50ms");
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			} else {
				System.out.println("视频慢");
			}
			preFrameNanoTime = System.nanoTime();
			preFrameTimestamp = videoWrapper.frame.timestamp;
//			graphicsContext.setFill(Color.GOLD);
//			graphicsContext.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
			graphicsContext.drawImage(videoWrapper.javafxImage, 0, 0);
		}
	}

	public void waitPlay() {
		synchronized (instance) {
			try {
				instance.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public void notifyPlay() {
		synchronized (instance) {
			instance.notifyAll();
		}
	}

	public void setRunning(Boolean isRunning) {
		this.isRunning = isRunning;
		if (isRunning != null && isRunning) {
			notifyPlay();
		}
		if (this.isRunning == null) {
			instance = null;
		}
	}

	public static void main(String[] args) {
		long startMillis = System.currentTimeMillis();
		long startNanos = System.nanoTime();
		System.out.println(startMillis);
		System.out.println(startNanos);
		new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		long endMillis = System.currentTimeMillis();
		long endNanos = System.nanoTime();
		System.out.println(endMillis);
		System.out.println(endNanos);
		System.out.println(endMillis - startMillis);
		System.out.println(endNanos - startNanos);

	}
}
